using System;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace Banshee.Controls
{
    public class ListView:System.Windows.Forms.ListView
    {
        public ListView()
        {
            SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
            columnHeaders = new HideableColumnCollection(this);
            base.View = System.Windows.Forms.View.Details;
        }
        private HideableColumnCollection columnHeaders = null;
        public HideableColumnCollection HideAbleColumns
        {
            get { return columnHeaders; }
        }

    }
    public class HideableColumnCollection:ListView.ColumnHeaderCollection
    {
        private SortedList columnList = new SortedList();
        public HideableColumnCollection(Banshee.Controls.ListView owner):base (owner) 
        {

        }
        public new HideableColumn this[int index]
        {
            get
            {
                return (HideableColumn)columnList.GetByIndex(index);
            }
        }
        public override ColumnHeader Add(string str, int width, HorizontalAlignment textAlign)
        {
            HideableColumn column = new HideableColumn(str, width, textAlign);
            this.Add(column);
            return column;
        }
        public override int Add(ColumnHeader column)
        {
            return this.Add(new HideableColumn(column));
        }
        public override void AddRange(ColumnHeader[] values)
        {
            for (int index = 0; index < values.Length; index++)
            {
                this.Add(new HideableColumn(values[index]));
            }
        }
        public int Add(HideableColumn column)
        {
            int retValue = base.Add(column);
            columnList.Add(column.ColumnID, column);
            column.VisibleChanged += new EventHandler(ColumnVisibleChanged);
            return retValue;
        }
        public new void Remove(ColumnHeader column)
        {
            base.Remove(column);
            columnList.Remove(((HideableColumn)column).ColumnID);
        }

        public new void RemoveAt(int index)
        {
            ColumnHeader column = this[index];
            this.Remove(column);
        }
        public new void Clear()
        {
            base.Clear();
            columnList.Clear();
        }
        private HideableColumn FindPreviousVisibleColumn(HideableColumn column)
        {
            int index = columnList.IndexOfKey(column.ColumnID);
            if (index > 0)
            {
                HideableColumn prevColumn = (HideableColumn)columnList.GetByIndex(index - 1);
                if ((prevColumn != null) && (prevColumn.Visible == false))
                {
                    prevColumn = FindPreviousVisibleColumn(prevColumn);
                }
                return prevColumn;
            }
            return null;
        }
        private void ColumnVisibleChanged(object sender, EventArgs e)
        {
            HideableColumn column = (HideableColumn)sender;

            if (column.Visible == true)
            {

                HideableColumn prevHeader = FindPreviousVisibleColumn(column);
                if (prevHeader == null)
                {

                    base.Insert(0, column);
                }
                else
                {

                    base.Insert(prevHeader.Index + 1, column);
                }
            }
            else
            {
                base.Remove(column);
            }
        }
    }
    public class HideableColumn : ColumnHeader
    {
        public HideableColumn()
        {

        }
        private int columnID = 0;
        private static int autoColumnID = 0;
        bool visible;

        public event EventHandler VisibleChanged;

        public bool Visible
        {
            get { return visible; }
            set { ShowColumn(value); }

        }
        public int ColumnID
        {
            get { return columnID; }
        }
        public new Banshee.Controls.ListView ListView
        {
            get { return (Banshee.Controls.ListView)base.ListView; }
        }
        public HideableColumn(string str, int width, HorizontalAlignment textAlign)
        {
            Initialize(str, width, textAlign);
        }

        public HideableColumn(ColumnHeader column)
        {
            Initialize(column.Text, column.Width, column.TextAlign);
        }
        public void ShowColumn(bool Visible)
        {
            if (this.visible != Visible)
            {
                this.visible = Visible;
                if (VisibleChanged != null)
                {
                    VisibleChanged(this, EventArgs.Empty);
                }
            }
        }
        private void Initialize(string str, int width, HorizontalAlignment textAlign)
        {
            base.Text = str;
            base.Width = width;
            base.TextAlign = textAlign;
            columnID = autoColumnID++;
        }
    }
}
